import torch
import torch.nn as nn


class LabelSmoothing(nn.Module):
    """NLL loss with label smoothing.
    """

    def __init__(self, smoothing=0.0, num_class=2):
        """Constructor for the LabelSmoothing module.
        :param smoothing: label smoothing factor
        """
        super(LabelSmoothing, self).__init__()
        self.num_class = num_class
        self.ave_smooth = smoothing / (num_class - 1)
        self.confidence = 1.0 - smoothing - self.ave_smooth
        # 此处的self.smoothing即我们的epsilon平滑参数。

    def forward(self, output, target):
        label_one_hot = torch.nn.functional.one_hot(target, self.num_class)
        label_smooth = label_one_hot * self.confidence + self.ave_smooth
        output_log_softmax=torch.log(output.exp()/output.exp().sum(axis=1).reshape(-1,1))
        loss = -(label_smooth * output_log_softmax).sum(axis=1)
        return loss.mean()

